{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 定义算法\n",
    "\n",
    "DQN 经验回放的算法中的均匀采样算法，可能会忘记一些重要的、以后使用的经验数据。针对这样的问题，PER_DQN 提出了优先级经验回放（prioritized experience reolay）的技术来解决，这种方法应用到 DQN 获得了更好的效果。PER_DQN 成功的原因有：\n",
    "1. 提出了sum tree这样复杂度为O(logn)的高效数据结构\n",
    "2. 正确估计了 weighted importance sampling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义模型\n",
    "\n",
    "同 DQN 。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class Model(nn.Module):\n",
    "    def __init__(self, n_states,n_actions,hidden_dim=128):\n",
    "        \"\"\" 初始化q网络，为全连接网络\n",
    "        \"\"\"\n",
    "        super(Model, self).__init__()\n",
    "        self.fc1 = nn.Linear(n_states, hidden_dim) # 输入层\n",
    "        self.fc2 = nn.Linear(hidden_dim,hidden_dim) # 隐藏层\n",
    "        self.fc3 = nn.Linear(hidden_dim, n_actions) # 输出层\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # 各层对应的激活函数\n",
    "        x = F.relu(self.fc1(x)) \n",
    "        x = F.relu(self.fc2(x))\n",
    "        return self.fc3(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义经验回放\n",
    "\n",
    "在实现上PER有两种方式，一个是简版PER，另一个就是接近原论文的SumTree PER，两者主要有以下不同：\n",
    "\n",
    "* 数据结构: 前者使用数组保存优先级，后者则用二叉树(SumTree)保存\n",
    "* 采样复杂度: 采样时前者是直接用概率分布随机，复杂度是 O(N)（慢）, 后者用树查找，复杂度是 O(log N)（快）\n",
    "* 更新优先级复杂度: 前者直接更新数组，O(1)（快）, 后者更新树上的节点，O(log N)（稍慢，但可以承受）\n",
    "* 内存开销: 小（1个数组）, 后者略大（1棵树 + 1个数据数组）\n",
    "* 适合场景： 小 buffer（比如几千条数据以内）, 大 buffer（比如一万到几十万条数据）\n",
    "\n",
    "这里默认使用SumTree PER, 想看简版实现以便于理解概念的同学可参考带\"SimpleBuffer\"字样的notebook\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "class SumTree:\n",
    "    def __init__(self, capacity):\n",
    "        self.capacity = capacity\n",
    "        self.tree = np.zeros(2 * capacity - 1) # 树的大小，叶节点数等于capacity\n",
    "        self.data = np.zeros(capacity, dtype=object)\n",
    "        self.data_pointer = 0\n",
    "\n",
    "    def add(self, priority, data):\n",
    "        '''向树中添加数据\n",
    "        '''\n",
    "        tree_idx = self.data_pointer + self.capacity - 1\n",
    "        self.data[self.data_pointer] = data\n",
    "        self.update(tree_idx, priority)\n",
    "        self.data_pointer += 1\n",
    "        if self.data_pointer >= self.capacity:\n",
    "            self.data_pointer = 0\n",
    "\n",
    "    def update(self, tree_idx, priority):\n",
    "        '''更新树中节点的优先级\n",
    "        '''\n",
    "        change = priority - self.tree[tree_idx]\n",
    "        self.tree[tree_idx] = priority\n",
    "        while tree_idx != 0:\n",
    "            tree_idx = (tree_idx - 1) // 2\n",
    "            self.tree[tree_idx] += change\n",
    "\n",
    "    def get_leaf(self, v):\n",
    "        '''根据给定的值v，找到对应的叶节点\n",
    "        '''\n",
    "        parent_idx = 0\n",
    "        while True:\n",
    "            left_child_idx = 2 * parent_idx + 1\n",
    "            right_child_idx = left_child_idx + 1\n",
    "            if left_child_idx >= len(self.tree):\n",
    "                leaf_idx = parent_idx\n",
    "                break\n",
    "            else:\n",
    "                if v <= self.tree[left_child_idx]:\n",
    "                    parent_idx = left_child_idx\n",
    "                else:\n",
    "                    v -= self.tree[left_child_idx]\n",
    "                    parent_idx = right_child_idx\n",
    "        data_idx = leaf_idx - self.capacity + 1\n",
    "        return leaf_idx, self.tree[leaf_idx], self.data[data_idx]\n",
    "    \n",
    "    @property\n",
    "    def max_priority(self):\n",
    "        '''获取当前树中最大的优先级\n",
    "        '''\n",
    "        return self.tree[-self.capacity:].max()\n",
    "        \n",
    "    @property\n",
    "    def total_priority(self):\n",
    "        '''获取当前树中所有优先级的和\n",
    "        '''\n",
    "        return self.tree[0]\n",
    "\n",
    "class ReplayBuffer:\n",
    "    def __init__(self, cfg):\n",
    "        self.capacity = cfg.buffer_size\n",
    "        self.alpha = cfg.per_alpha\n",
    "        self.beta = cfg.per_beta\n",
    "        self.beta_increment_per_sampling = cfg.per_beta_increment_per_sampling\n",
    "        self.epsilon = cfg.per_epsilon\n",
    "        self.tree = SumTree(self.capacity)\n",
    "        \n",
    "    def push(self, transition):\n",
    "        # max_prio = self.tree.tree[-self.tree.capacity:].max()\n",
    "        max_prio = self.tree.max_priority\n",
    "        if max_prio == 0:\n",
    "            max_prio = 1.0\n",
    "        self.tree.add(max_prio, transition)\n",
    "\n",
    "    def sample(self, batch_size):\n",
    "        self.beta = min(1.0, self.beta + self.beta_increment_per_sampling)\n",
    "        minibatch = []\n",
    "        idxs = []\n",
    "        segment = self.tree.total_priority / batch_size\n",
    "        priorities = []\n",
    "\n",
    "        for i in range(batch_size):\n",
    "            a = segment * i\n",
    "            b = segment * (i + 1)\n",
    "            s = np.random.uniform(a, b)\n",
    "            idx, p, data = self.tree.get_leaf(s)\n",
    "            minibatch.append(data)\n",
    "            idxs.append(idx)\n",
    "            priorities.append(p)\n",
    "\n",
    "        sampling_probabilities = priorities / self.tree.total_priority\n",
    "        is_weight = np.power(self.tree.capacity * sampling_probabilities, -self.beta)\n",
    "        is_weight /= is_weight.max()\n",
    "\n",
    "        batch = list(zip(*minibatch))\n",
    "        return tuple(map(lambda x: np.array(x), batch)), idxs, is_weight\n",
    "\n",
    "    def update_priorities(self, idxs, priorities):\n",
    "        for idx, priority in zip(idxs, priorities):\n",
    "            self.tree.update(idx, (np.abs(priority) + self.epsilon) ** self.alpha)\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.tree.data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义策略\n",
    "\n",
    "同 DQN 。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.optim as optim\n",
    "import math\n",
    "import numpy as np\n",
    "import random\n",
    "\n",
    "\n",
    "class Policy:\n",
    "    def __init__(self, cfg):\n",
    "        self.action_dim = cfg.action_dim  # 动作空间的维度\n",
    "        self.device = torch.device(cfg.device) # CPU或GPU \n",
    "        self.gamma = cfg.gamma  # 奖励的折扣因子\n",
    "        ## e-greedy策略相关参数\n",
    "        self.sample_count = 0  # 用于epsilon的衰减计数\n",
    "        self.epsilon = cfg.epsilon_start\n",
    "        self.epsilon_start = cfg.epsilon_start\n",
    "        self.epsilon_end = cfg.epsilon_end\n",
    "        self.epsilon_decay = cfg.epsilon_decay\n",
    "        self.batch_size = cfg.batch_size\n",
    "        self.target_update = cfg.target_update\n",
    "        # 当前网络和目标网络\n",
    "        self.model = Model(cfg.state_dim, cfg.action_dim, hidden_dim = cfg.hidden_dim).to(self.device)\n",
    "        self.target_model = Model(cfg.state_dim, cfg.action_dim, hidden_dim = cfg.hidden_dim).to(self.device)\n",
    "        # # 复制参数到目标网络\n",
    "        # for target_param, param in zip(self.target_model.parameters(),self.model.parameters()): \n",
    "        #     target_param.data.copy_(param.data)\n",
    "        self.target_model.load_state_dict(self.model.state_dict()) # 复制参数到目标网络\n",
    "        self.optimizer = optim.Adam(self.model.parameters(), lr=cfg.lr) \n",
    "        self.memory = ReplayBuffer(cfg) # 经验回放\n",
    "        self.update_cnt = 0\n",
    "        \n",
    "    def sample_action(self, state):\n",
    "        ''' sample action with e-greedy policy\n",
    "        '''\n",
    "        self.sample_count += 1\n",
    "        # epsilon 指数衰减\n",
    "        self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \\\n",
    "            math.exp(-1. * self.sample_count / self.epsilon_decay) \n",
    "        if random.random() > self.epsilon:\n",
    "            action = self.predict_action(state) # 预测动作\n",
    "        else:\n",
    "            action = random.randrange(self.action_dim) # 随机动作, 便于前期探索\n",
    "        return action\n",
    "    \n",
    "    @torch.no_grad()\n",
    "    def predict_action(self, state):\n",
    "        ''' 预测动作\n",
    "        '''\n",
    "        state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) # [1, state_dim]\n",
    "        q_values = self.model(state)\n",
    "        action = q_values.max(1)[1].item() \n",
    "        return action\n",
    "    \n",
    "    def get_policy_params(self):\n",
    "        ''' 获取当前策略的参数\n",
    "        '''\n",
    "        return self.model.state_dict()\n",
    "    \n",
    "    def load_policy_params(self, params):\n",
    "        ''' 加载策略参数\n",
    "        '''\n",
    "        self.model.load_state_dict(params)\n",
    "    \n",
    "    def update(self):\n",
    "        if len(self.memory) < self.batch_size: # 不满足一个批量时，不更新策略\n",
    "            return\n",
    "        # 采样一个batch\n",
    "        (states, actions, rewards, next_states, dones), idxs, weights = self.memory.sample(\n",
    "            self.batch_size)\n",
    "        states = torch.tensor(np.array(states), device=self.device, dtype=torch.float) # [B, state_dim]]\n",
    "        actions = torch.tensor(actions, device=self.device, dtype=torch.int64).unsqueeze(1) # [B,1]\n",
    "        rewards = torch.tensor(rewards, device=self.device, dtype=torch.float).unsqueeze(1) # [B,1]\n",
    "        next_states = torch.tensor(np.array(next_states), device=self.device, dtype=torch.float) # [B, state_dim]]\n",
    "        dones = torch.tensor(np.float32(dones), device=self.device).unsqueeze(1) # [B,1]\n",
    "        weights = torch.tensor(weights, device=self.device, dtype=torch.float).unsqueeze(1) # [B,1]\n",
    "\n",
    "        q_value = self.model(states).gather(dim=1, index=actions) # [B,1]\n",
    "        next_q_value_max = self.target_model(next_states).max(1)[0].detach().unsqueeze(1) \n",
    "        expected_q_value = rewards + self.gamma * next_q_value_max* (1-dones)\n",
    "        td_errors = abs(q_value - expected_q_value)\n",
    "\n",
    "        # loss中根据优先度进行了加权\n",
    "        loss = (td_errors ** 2 * weights).mean()\n",
    "\n",
    "        priorities = td_errors.squeeze().cpu().detach().numpy() + 1e-5 # 计算TD误差\n",
    "        # 需要更新样本的优先度\n",
    "        self.memory.update_priorities(idxs, priorities) \n",
    "\n",
    "        # 反向传播\n",
    "        self.optimizer.zero_grad()  \n",
    "        loss.backward()\n",
    "        # 梯度截断，防止梯度爆炸\n",
    "        for param in self.model.parameters():  \n",
    "            param.grad.data.clamp_(-1, 1)\n",
    "        self.optimizer.step() \n",
    "        self.update_cnt += 1\n",
    "        if self.update_cnt % self.target_update == 0: # 更新 target_model\n",
    "            self.target_model.load_state_dict(self.model.state_dict()) \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 设置参数和定义可视化函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import os\n",
    "\n",
    "def smooth(data: list, weight: float = 0.9):\n",
    "    '''用于平滑曲线, 类似于Tensorboard中的smooth曲线\n",
    "    '''\n",
    "    last = data[0] \n",
    "    smoothed = []\n",
    "    for point in data:\n",
    "        smoothed_val = last * weight + (1 - weight) * point  # 计算平滑值\n",
    "        smoothed.append(smoothed_val)                    \n",
    "        last = smoothed_val                                \n",
    "    return smoothed\n",
    "\n",
    "def plot_rewards(cfg, frames, rewards):\n",
    "    ''' 画图\n",
    "    '''\n",
    "    sns.set_theme(style=\"darkgrid\")\n",
    "    plt.figure()  # 创建一个图形实例，方便同时多画几个图\n",
    "    plt.title(f\"{cfg.mode}ing curve on {cfg.device} of {cfg.algo_name} for {cfg.env_id}\")\n",
    "    plt.xlabel('frames')\n",
    "    plt.plot(frames, rewards, label='rewards')\n",
    "    plt.plot(frames, smooth(rewards), label='smoothed rewards')\n",
    "    plt.legend()\n",
    "    plt.show()\n",
    "\n",
    "def print_cfgs(cfg):\n",
    "    ''' 打印参数\n",
    "    '''\n",
    "    cfg_dict = vars(cfg)\n",
    "    print(\"Hyperparameters:\")\n",
    "    print(''.join(['=']*80))\n",
    "    tplt = \"{:^20}\\t{:^20}\\t{:^20}\"\n",
    "    print(tplt.format(\"Name\", \"Value\", \"Type\"))\n",
    "    allow_types = ['int', 'float', 'str', 'bool', 'list', 'dict']\n",
    "    for k,v in cfg_dict.items():\n",
    "        if v.__class__.__name__ == 'list':\n",
    "            v = str(v)\n",
    "        if v.__class__.__name__ not in allow_types:\n",
    "            continue\n",
    "        print(tplt.format(k,v,str(type(v))))   \n",
    "    print(''.join(['=']*80))\n",
    "\n",
    "def all_seed(seed: int = 0):\n",
    "    ''' 设置随机种子\n",
    "    '''\n",
    "    if seed == 0:\n",
    "        return\n",
    "    np.random.seed(seed)\n",
    "    random.seed(seed)\n",
    "    torch.manual_seed(seed) # config for CPU\n",
    "    torch.cuda.manual_seed(seed) # config for GPU\n",
    "    os.environ['PYTHONHASHSEED'] = str(seed) # config for python scripts\n",
    "    # config for cudnn\n",
    "    torch.backends.cudnn.deterministic = True\n",
    "    torch.backends.cudnn.benchmark = False\n",
    "    torch.backends.cudnn.enabled = False  \n",
    "\n",
    "class Config:\n",
    "    def __init__(self) -> None:\n",
    "        self.algo_name = 'PER_DQN' # 算法名称\n",
    "        self.env_id = 'CartPole-v1' # 环境id\n",
    "        self.mode = 'train'\n",
    "        self.seed = 1 # 随机种子，便于复现，0表示不设置\n",
    "        self.max_epsiode = 200 # 训练的回合数\n",
    "        self.max_epsiode_test = 20 # 测试的回合数\n",
    "        self.max_step = 200 # 每个回合的最大步数，超过该数则游戏强制终止\n",
    "        self.gamma = 0.99 # 折扣因子\n",
    "        self.epsilon_start = 0.95 # e-greedy策略中初始epsilon\n",
    "        self.epsilon_end = 0.01 # e-greedy策略中的终止epsilon\n",
    "        self.epsilon_decay = 500 # e-greedy策略中epsilon的衰减率\n",
    "        self.hidden_dim = 256 # 神经网络的隐藏层维度\n",
    "        self.batch_size = 64 # 批次大小\n",
    "        self.target_update = 100 # 目标网络的更新频率\n",
    "        self.lr = 0.0001 # 学习率\n",
    "        #region buffer相关参数\n",
    "        self.buffer_size = 100000 # 经验回放池的容量\n",
    "        self.per_alpha = 0.6 # 优先级的指数 \n",
    "        self.per_epsilon = 1e-5 # 优先级的最小值\n",
    "        self.per_beta = 0.4 # beta的初始值\n",
    "        self.per_beta_increment_per_sampling = 0.0001 # beta的增量\n",
    "        #endregion\n",
    "        self.device = 'cpu' if not torch.cuda.is_available() else 'cuda'\n",
    "        self.reward_threshold = 200 # 奖励阈值，达到该值则认为训练成功\n",
    "        self.reward_threshold_limit = 10 # 累计一定训练成功次数后停止训练, 这样可以避免训练过长时间"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import gymnasium as gym\n",
    "\n",
    "def make_env(cfg: Config):\n",
    "    ''' 创建环境\n",
    "    '''\n",
    "    env = gym.make(cfg.env_id) # 创建环境\n",
    "    setattr(cfg, \"action_space\", env.action_space) # 动作空间\n",
    "    setattr(cfg, \"state_dim\", env.observation_space.shape[0]) # 状态维度\n",
    "    setattr(cfg, \"action_dim\", env.action_space.n) # 动作维度\n",
    "    return env\n",
    "\n",
    "def train(cfg: Config, env, policy):\n",
    "    ''' 训练\n",
    "    '''\n",
    "    rewards = []  # 记录所有回合的奖励\n",
    "    best_policy_params = None  # 最佳策略\n",
    "    best_ep_reward = float('-inf') # 最佳回合的奖励\n",
    "    reward_threshold_cnt = 0 # 奖励阈值计数器\n",
    "    frames = []\n",
    "    for i_ep in range(cfg.max_epsiode):\n",
    "        ep_reward = 0  # 记录一回合内的奖励\n",
    "        ep_step = 0\n",
    "        state, info = env.reset(seed = cfg.seed)  # 重置环境，返回初始状态\n",
    "        for _ in range(cfg.max_step):\n",
    "            ep_step += 1\n",
    "            action = policy.sample_action(state)  # 选择动作\n",
    "            next_state, reward, terminated, truncated , info = env.step(action)  # 更新环境，返回transition\n",
    "            policy.memory.push((state, action, reward, next_state, float(truncated or terminated)))   # 保存transition\n",
    "            state = next_state  # 更新下一个状态\n",
    "            policy.update()  # 更新智能体\n",
    "            ep_reward += reward  # 累加奖励\n",
    "            if terminated:\n",
    "                if ep_reward >= best_ep_reward:  # 更新最佳策略\n",
    "                    best_ep_reward = ep_reward\n",
    "                    best_policy_params = policy.model.state_dict()\n",
    "                    print(f\"更新最佳策略，回合：{i_ep+1}/{cfg.max_epsiode}, 最佳奖励：{best_ep_reward:.2f}\")\n",
    "                if ep_reward >= cfg.reward_threshold:\n",
    "                    reward_threshold_cnt += 1\n",
    "                break\n",
    "        rewards.append(ep_reward)\n",
    "        frames.append(i_ep)\n",
    "        if reward_threshold_cnt >= cfg.reward_threshold_limit:\n",
    "            print(f\"达到奖励阈值累计{cfg.reward_threshold_limit}次, 训练成功，回合：{i_ep+1}/{cfg.max_epsiode}，奖励：{ep_reward:.2f}\")\n",
    "            break\n",
    "        if (i_ep + 1) % 10 == 0:\n",
    "            print(f\"回合：{i_ep+1}/{cfg.max_epsiode}，奖励：{ep_reward:.2f}, Epislon: {policy.epsilon:.3f}\")\n",
    "    env.close()\n",
    "    return {'rewards':rewards, 'frames':frames, 'best_policy_params':best_policy_params} # 返回训练结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 开始训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hyperparameters:\n",
      "================================================================================\n",
      "        Name        \t       Value        \t        Type        \n",
      "     algo_name      \t      PER_DQN       \t   <class 'str'>    \n",
      "       env_id       \t    CartPole-v1     \t   <class 'str'>    \n",
      "        mode        \t       train        \t   <class 'str'>    \n",
      "        seed        \t         1          \t   <class 'int'>    \n",
      "    max_epsiode     \t        200         \t   <class 'int'>    \n",
      "  max_epsiode_test  \t         20         \t   <class 'int'>    \n",
      "      max_step      \t        200         \t   <class 'int'>    \n",
      "       gamma        \t        0.99        \t  <class 'float'>   \n",
      "   epsilon_start    \t        0.95        \t  <class 'float'>   \n",
      "    epsilon_end     \t        0.01        \t  <class 'float'>   \n",
      "   epsilon_decay    \t        500         \t   <class 'int'>    \n",
      "     hidden_dim     \t        256         \t   <class 'int'>    \n",
      "     batch_size     \t         64         \t   <class 'int'>    \n",
      "   target_update    \t        100         \t   <class 'int'>    \n",
      "         lr         \t       0.0001       \t  <class 'float'>   \n",
      "    buffer_size     \t       100000       \t   <class 'int'>    \n",
      "     per_alpha      \t        0.6         \t  <class 'float'>   \n",
      "    per_epsilon     \t       1e-05        \t  <class 'float'>   \n",
      "      per_beta      \t        0.4         \t  <class 'float'>   \n",
      "per_beta_increment_per_sampling\t       0.0001       \t  <class 'float'>   \n",
      "       device       \t        cpu         \t   <class 'str'>    \n",
      "  reward_threshold  \t        200         \t   <class 'int'>    \n",
      "reward_threshold_limit\t         10         \t   <class 'int'>    \n",
      "     state_dim      \t         4          \t   <class 'int'>    \n",
      "================================================================================\n",
      "更新最佳策略，回合：1/200，奖励：23.00\n",
      "更新最佳策略，回合：5/200，奖励：26.00\n",
      "更新最佳策略，回合：8/200，奖励：38.00\n",
      "回合：10/200，奖励：18.00, Epislon: 0.652\n",
      "回合：20/200，奖励：20.00, Epislon: 0.457\n",
      "回合：30/200，奖励：18.00, Epislon: 0.322\n",
      "更新最佳策略，回合：31/200，奖励：70.00\n",
      "更新最佳策略，回合：38/200，奖励：78.00\n",
      "回合：40/200，奖励：63.00, Epislon: 0.129\n",
      "更新最佳策略，回合：41/200，奖励：90.00\n",
      "更新最佳策略，回合：42/200，奖励：176.00\n",
      "回合：50/200，奖励：200.00, Epislon: 0.013\n",
      "回合：60/200，奖励：200.00, Epislon: 0.010\n",
      "回合：70/200，奖励：200.00, Epislon: 0.010\n",
      "回合：80/200，奖励：200.00, Epislon: 0.010\n",
      "更新最佳策略，回合：84/200，奖励：196.00\n",
      "回合：90/200，奖励：200.00, Epislon: 0.010\n",
      "更新最佳策略，回合：92/200，奖励：200.00\n",
      "回合：100/200，奖励：200.00, Epislon: 0.010\n",
      "回合：110/200，奖励：200.00, Epislon: 0.010\n",
      "回合：120/200，奖励：200.00, Epislon: 0.010\n",
      "回合：130/200，奖励：200.00, Epislon: 0.010\n",
      "回合：140/200，奖励：200.00, Epislon: 0.010\n",
      "回合：150/200，奖励：200.00, Epislon: 0.010\n",
      "回合：160/200，奖励：200.00, Epislon: 0.010\n",
      "回合：170/200，奖励：200.00, Epislon: 0.010\n",
      "回合：180/200，奖励：200.00, Epislon: 0.010\n",
      "回合：190/200，奖励：200.00, Epislon: 0.010\n",
      "回合：200/200，奖励：200.00, Epislon: 0.010\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAHJCAYAAACrCBICAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB6u0lEQVR4nO3dB5gT1doH8H/K9r4LLF16E2kCggooKnLtitd7LSiKivopV+y9o6goiIqIoKiAHRQ7tqvCFaSoIL13FliWXbZmU77nPcmEJJvtye5k9v97njzZTZ2TSWbeec97zphcLpcLRERERDpkru8FICIiIioPAxUiIiLSLQYqREREpFsMVIiIiEi3GKgQERGRbjFQISIiIt1ioEJERES6xUCFiIiIdIuBSgTjXH1EZHTczhEDlQj1ww8/4N577w3Ja82bNw+dO3fG7t27w/ocalhmzZqFU045BT169MDUqVODPka+Q4EXefy5556LN954A06n0/vYkSNHBn28drnssssqfGyXLl3Qp08fXHLJJfjss8+q3Z777ruvzOv16tUL559/Pl555RUUFxcHfd6GDRvwwAMPYOjQoaptp512Gu644w789ddf5b7H999/H/S1pF1yqciSJUtw9tlno3v37rj++usRLr/99htuvfVWDBo0CD179lTv+eyzzyI7Oztk7yHfm5kzZ5bZ7vheunbtin79+uG6667DihUrqvX6S5cuVa8h13VtwoQJla5LcrN6rikCdwKhIhvODz74AE2aNAnrc6jhyM/PVzst+Z7IDqRly5blPvbSSy/FP//5T+//RUVFWLhwISZOnIi8vDzceeed3vu6deuGRx99NOjrJCQk+P0f+FiHw4H9+/er384999yD1NRUDBkypFrtaty4sQpKhARRR48exfLly/H6669j0aJFePvttxETE+N9/KeffoqHH35YLcttt92GFi1aqGX4+OOPcfnll+Puu+/GtddeW+Z9ZLn79u2rlrG6nnvuObVs06dPR0ZGBsJB1s2MGTMwfPhwPPjgg2o5JSCT4FLW3ezZs9GsWbNav89LL72kgqFAsg5kXQhp66FDh/Dqq6/immuuUZ+tBJF69uabb+Ktt95C//7963tRIgIDFUJ6erq6hPs51HDk5uaqHciZZ56pjnYr0rRpU5WZ8DVw4EBs3boVc+bMwdixYxEVFaVuT0xM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448/joEDB6rv8Z133onDhw+HdiFdVMbLL7/sOumkk1w//fSTa926da7rrrvONWzYMFdJSYkrEl177bWu8847z7Vs2TLX1q1bXY8//rirR48eri1btqj7Bw4c6Jo7d67rwIED3ktOTo4rkvz3v/91nXDCCa6srCy/dhQVFbkOHz6s1uf999/v2rx5s+vjjz9Wj5XrSCDfO982yWXhwoWuzp07e9vwn//8x3X33XeXeVwkmD17tqtLly6uq666yntbVdZZJP1Og7VRfo9du3Z1vfbaa65t27ap7/DgwYNd9913n/cxc+bMcZ155pll1qve2hisfeLSSy91vfjii37Lnp2dbZh1KNtJ37bJ9ueKK65wnXvuua78/Hz1GPn+durUSbXP97Ha/XreP2zevFn97mQdyt8zZsxwdevWzfW///3P+3z5vsp3VJ7/119/uS666CLXlVdeGdJlZKASQH4gvXv3VhsITW5urlpxn3/+uSvSbN++Xf1Ili9f7r3N6XSqL9bkyZNdhw4dUvevWbPGFcmmT5/uOv/884PeN23aNNepp57qKi0t9d72wgsvqA1iJCooKHCdfvrpfju0f/zjH6633nrLFUn279/vGjNmjKtXr16u4cOH++0AKltnkfI7raiNd955p2vUqFF+j58/f77r+OOP9+6oH330UddNN93k0quK2ifbGbldgupgjLAOA7377ruu7t27ew8CxZdffunq06ePKxL3Dw8//LAKNn3dcccdKqDUPhsJ3iTI1kiwI6+5cuXKkC0nu34CrF+/HgUFBSqNpUlOTka3bt2wbNkyRJq0tDRMnz4dJ5xwgvc2k8mkLnl5ediwYYP6u23btohk0o727dsHvU/SmP3794fVavXeNmDAAGzfvh2HDh1CpJk2bRqKiopw7733qv9tNptqS7t27RBJ1qxZg6ioKCxYsECllauzziLld1pRG6+77jrvOtSYzWaUlpYiPz+/0u+13tu3c+dOFBYWlvu9NMI69CXdHZMnT8bNN9/s12Y9r8O0SvYP8jv0XT/a71C6JCXRIdfabRrZl2RmZoZ0HR7bCpCyf/9+dd2sWTO/25s0aeK9L5LID3/IkCF+t3377bfYsWMHHnjgAWzcuBFJSUl44oknsHjxYsTHx6t+yFtuuQXR0dGIFNIO+dFdeeWV2LZtG4477ji1wZB+V1lvnTp1KrM+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6T6Ss1/LmZPlbzn77o8//oitW7eqE/f17NlTneX1yy+/9FsOeX/tjK3yGHmsnGna1xdffIELLrhAvbeczfauu+5Sp6InIv3jSQmJqEYkGJCz48r1K6+8gh07dqgzHMuZjrWz4Q4bNgzz58/HU089pU5rL2f/zc3NVWfTlefJWYKbNm2qApUHH3xQZWfkLKzNmjVTZw3euXOnOlPw5Zdfji5duqj3+euvv/D999+r5x0+fBgXXXSR6nKS58m1dEf9/fff+Pjjj9WZalesWKGCqFtuuUWdnVfqaqSrqk2bNupMxESkb+z6IaIa6datG9LT0xEdHa0yJSUlJer2K664AsOHD/c+bteuXRg9erQKFDQtWrRQGRYJIs4991x1m9PpxE033YR//vOf6v+8vDyMGzdOZUiuvfZadVtSUpLKuEggIoGKBCXS/fTee++p19ROMy9dUS+99BKmTJmi3iM2NhY33nijWlaRmpqK1atXQ47TTCZTHX5qRFRdDFSIKKS6du3q9/99993nDTykG0cyL0uXLlW32Ww2v8f27t3b+3dGRoa6lu4cjQQY2muJ3377Tb2fFPLa7XZ1m9lsVsHKggUL1P+SRZk0aRLOO+881Z00ZMgQnHrqqeqaiPSPgQoRhVR8fLzf/9J988gjj6igIioqCu3atVPdOCKw5zkxMbHM61U0kkiyKRL4HH/88UHvl+HSEvxMnz4ds2bNwltvvaX+lu4kyd5IlxAR6RsDFSIKG+nOkS4XCVCkZkSyH1arFZs3b8Znn31W69eXriApopXamGC0rp5BgwapiwQuS5YswTvvvKPqZiRbIwW2RKRfHPVDRGGTk5ODbdu24dJLL1UjeSRIEb/88os3kKkNCVLk9du2bateX7tIECSBkcViwbPPPqvqWiR7I9kZGZF07733ekcMEZG+MaNCRGEjdSZS5DpnzhxV/JqcnIxff/1VZTREbWeyHTVqlApK5Pq6665DWloavvrqK3z44Ye4//771WNkOLJ0+UitjAxRLi0txYwZM1S9i9xHRPrGjAoRhdXUqVNVsasECrfffrsaXvzaa6+pWhWZN6U25HVl3hYJhh577DFVd7Jq1SqMHz9eBS9CimZlqPOmTZvUEGaZc0UyKxIsacW5RKRfnEeFiIiIdIsZFSIiItItBipERESkWwxUiIiISLcYqBAREZFuMVAhIiIi3WKgQkRERLrFQIWIiIh0i4EKERER6RYDFSIiItItBipERESkWwxUiIiICHr1/94nGAs01KMPAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 获取参数\n",
    "cfg = Config() \n",
    "env = make_env(cfg) # 创建环境\n",
    "policy = Policy(cfg)\n",
    "all_seed(cfg.seed)\n",
    "print_cfgs(cfg)\n",
    "res = train(cfg,env,policy) # 训练\n",
    "plot_rewards(cfg, res['frames'], res['rewards'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回合：1/20，奖励：200.00\n",
      "回合：2/20，奖励：200.00\n",
      "回合：3/20，奖励：200.00\n",
      "回合：4/20，奖励：200.00\n",
      "回合：5/20，奖励：200.00\n",
      "回合：6/20，奖励：200.00\n",
      "回合：7/20，奖励：200.00\n",
      "回合：8/20，奖励：200.00\n",
      "回合：9/20，奖励：200.00\n",
      "回合：10/20，奖励：200.00\n",
      "回合：11/20，奖励：200.00\n",
      "回合：12/20，奖励：200.00\n",
      "回合：13/20，奖励：200.00\n",
      "回合：14/20，奖励：200.00\n",
      "回合：15/20，奖励：200.00\n",
      "回合：16/20，奖励：200.00\n",
      "回合：17/20，奖励：200.00\n",
      "回合：18/20，奖励：200.00\n",
      "回合：19/20，奖励：200.00\n",
      "回合：20/20，奖励：200.00\n"
     ]
    },
    {
     "data": {
      "image/png": "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c+d2Z9WJiIjIJFwON+fPn5dRo0ZJtWrV1P1sbt26pe55g8f9+/elefPmcujQIdVMhZv4zZkzRzU/tW3b1m45GB6OcONMRESEWh6arqBChQpq3D7ul4P+N4cPH1a1RqjNqV+//suWnYiIiMwcbjAyCs1JGzdulPLly9s9MNw7T548MnXqVNm6davUq1dPli5dqoZ74x43thBe0qZN6/Q9rl69qpa3bt06a1MXOh+j5qZx48bSsmVL1cSFuxkbzWFEREREtjwsJvyLa+h0defOwwS5dw6GmIeGPtS+U5eZymq28rKs+jJTeVlW/QQG+rk8WkqHO1cRERERWTHcEBERkVYYboiIiEgrDDdERESkFYYbIiIi0grDDREREWmF4YaIiIi0wnBDREREWmG4ISIiIq0w3BAREZFWGG6IiIhIKww3REREpBWGGyIiItIKww0RERFpheGGiIiItMJwQ0RERFphuCEiIiKtMNwQERGRVhhuiIiISCsMN0RERKQVhhsiIiLSCsMNERERaYXhhoiIiLTCcENERERaYbghIiIirTDcEBERkVYYboiIiEgrDDdERESkFYYbIiIi0grDDREREZk73Ny9e1eGDBkiFSpUkOLFi0vjxo1l37591td37dol9evXlyJFikiNGjVk7dq1dvPv379f8uXLF+WxZ8+eaN/z0qVL0qFDB/V+5cuXlwkTJkhERIS7q05EREQm4O3uDD179pSbN2/K+PHjJV26dDJ//nxp06aNrFixQiwWiwohrVq1krFjx8qWLVukT58+EhgYKOXKlVPznzx5Ut544w1ZuHCh3XLTpEnj9P2eP3+ulp89e3ZZvHixXLhwQQYOHCienp7StWvXuJabiIiINOVWuAkJCZGdO3eqYFKiRAn13ODBg2X79u2yevVquX37tqqF6dGjh3otV65ccuzYMZk1a5Y13Jw6dUpy584tGTJkcOk9N2zYIFeuXJElS5aoAJQ3b171PmPGjJGOHTuKj4+P+6UmIiIibbkVbgICAiQoKEgKFSpkfc7Dw0M9wsLCVPNU1apV7eYpW7asjBw5UtXqYDrU3BjByBVYZsGCBe1qdrDMBw8eyPHjx1XzV1x4e8d/dyMvL0+7nzozU1nNVl6WVV9mKi/Lam5uhRt/f3+pWLFilJoV1OgMGDBANU1lzpzZ7vWMGTPK48ePJTQ0VDVPnT59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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def test(cfg, env, policy: Policy):\n",
    "    ''' 测试\n",
    "    '''\n",
    "    rewards = []  # 记录所有回合的奖励\n",
    "    frames = []\n",
    "    for i_ep in range(cfg.max_epsiode_test):\n",
    "        ep_reward = 0  # 记录一回合内的奖励\n",
    "        state, info = env.reset(seed = cfg.seed)  # 重置环境，返回初始状态\n",
    "        for _ in range(cfg.max_step):\n",
    "            action = policy.predict_action(state)  # 选择动作\n",
    "            next_state, reward, terminated, truncated , info = env.step(action)  # 更新环境，返回transition\n",
    "            state = next_state  # 更新下一个状态\n",
    "            ep_reward += reward  # 累加奖励\n",
    "            if terminated or truncated:\n",
    "                break\n",
    "        rewards.append(ep_reward)\n",
    "        frames.append(i_ep)\n",
    "        print(f\"回合：{i_ep+1}/{cfg.max_epsiode_test}，奖励：{ep_reward:.2f}\")\n",
    "    env.close()\n",
    "    return {'rewards':rewards, 'frames':frames}\n",
    "cfg.mode = 'test' # 测试模式\n",
    "test_env = make_env(cfg)\n",
    "test_policy = Policy(cfg)\n",
    "test_policy.load_policy_params(res['best_policy_params']) # 加载训练时的最佳策略参数\n",
    "test_res = test(cfg, test_env, test_policy)\n",
    "plot_rewards(cfg, test_res['frames'], test_res['rewards'])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "joyrl-book",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
